package org.springblade.modules.admin.controller.feishu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.lark.oapi.Client;
import com.lark.oapi.service.bitable.v1.model.*;
import com.lark.oapi.service.im.v1.model.CreateMessageReq;
import com.lark.oapi.service.im.v1.model.CreateMessageReqBody;
import com.lark.oapi.service.im.v1.model.CreateMessageResp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.config.FeiShuConfiguration;
import org.springblade.common.enums.FeiShuDocumentEnum;
import org.springblade.common.enums.FeishuClientEnum;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.entity.ElevatorAudit;
import org.springblade.modules.admin.entity.feishu.FeiShuTableAnnualReviewDateCopyTemplate;
import org.springblade.modules.admin.entity.feishu.FeiShuTableAnnualReviewDateTemplate;
import org.springblade.modules.admin.service.ElevatorAuditService;
import org.springblade.modules.admin.service.feishu.IFeiShuDocumentService;
import org.springblade.modules.admin.vo.feishu.FeiShuAnnualReviewDateVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 飞书年审日期控制器
 * @author: Sharry
 * @createTime: 2024-04-22 9:15
 * @version: Version-1.0
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/admin/feishu/annual-review-date")
@Api(value = "/admin/feishu/annual-review-date", tags = "飞书年审日期写回梯无忧")
public class FeiShuAnnualReviewDateController {

	@Autowired
	private FeiShuConfiguration feiShuConfiguration;

	@Autowired
	private IFeiShuDocumentService feiShuDocumentService;

	@Autowired
	private ElevatorAuditService elevatorAuditService;

	@GetMapping("/copy")
	@ApiOperation("测试环境根据设备注册代码将数据写回副本")
	@ApiOperationSupport(order = 10)
	public R<Boolean> copy() {
		// 1. 创建 Client 对象
		Client client = feiShuConfiguration.getClient(FeishuClientEnum.TABLE);
		// 获取 appToken 和 tableId
		String appToken = FeiShuDocumentEnum.ELEVATOR_ANNUAL_REVIEW_DATE_COPY.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_ANNUAL_REVIEW_DATE_COPY.getTableId();
		// 发起初始请求
		SearchAppTableRecordResp resp = null;
		try {
			resp = feiShuDocumentService.getRecordsByCondition(client,appToken,tableId,new SearchAppTableRecordReqBody(),null);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		// 处理服务端错误
		if(!resp.success()) {
			throw new ServiceException(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));
		}
		// 定义 Items 接受对象并接受第一次请求的对象，持续接受 Items 直到没有更多数据
        List<AppTableRecord> items = new ArrayList<>(Arrays.asList(resp.getData().getItems()));
		// 若存在下一页,则继续请求下一页，直到没有更多数据
		while(resp.getData().getHasMore()){
			// 定义下一页请求对象, 其中，查询参数请参考飞书官方文档
			String pageToken = resp.getData().getPageToken();
			resp = feiShuDocumentService.getRecordsByCondition(client,appToken,tableId,new SearchAppTableRecordReqBody(),pageToken);
			if(!resp.success()) {
				throw new ServiceException(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));
			}
			items.addAll(Arrays.asList(resp.getData().getItems()));
		}
		// 2. 业务数据处理：根据设备注册代码同步飞书的年审日期进梯无忧，同步的行，飞书表格单选框选择。
		boolean isSuccess = true;
		// 可同步至梯无忧的targets
		Map<String, Object> targetsMap = new HashMap<>(100);
		// 同步对象列表
		List<ElevatorAudit> targetElevatorAuditList = new ArrayList<>();
		// 用于筛选的 deviceCodes
		List<String> deviceCodes = new ArrayList<>();
		// 筛选结果
		List<FeiShuAnnualReviewDateVO> annualReviewDateVOList = new ArrayList<>();
		// recordId， deviceCode Map, 用于记录已同步的记录
		Map<String, String> recordIdDeviceCodeMap = new HashMap<>();
		// 飞书更新对象列表
		List<AppTableRecord> updateRecords = new ArrayList<>();

		// 当 items 为空时
		if(Func.isEmpty(items)){
			return R.data(true);
		}

		// 当 items 不为空时
		items.forEach(i -> {
			// 适配最新的FeiShuAPI，以下是所需数据转换
			String deviceCode = null;
			Long annualReviewDate = null;
			String recordId = i.getRecordId();
			Object deviceCodeObj = i.getFields().get("设备注册代码");

			if(!Func.isNull(deviceCodeObj)){
				// 将 deviceCodeObj 转换为 jsonArray
				String deviceCodeObjJsonArrayStr = JSON.toJSONString(deviceCodeObj);
				JSONArray deviceCodeJsonArray = JSON.parseArray(deviceCodeObjJsonArrayStr);
				Object deviceCodeObject = deviceCodeJsonArray.get(0);
				// 将 deviceCodeObject 转换为JsonObject
				String deviceCodeJsonObjectStr = JSON.toJSONString(deviceCodeObject);
				JSONObject deviceCodeJsonObject = JSON.parseObject(deviceCodeJsonObjectStr);
				deviceCode = deviceCodeJsonObject.getString("text");
				deviceCodes.add(deviceCode);
			}
			Object nextAnnualReviewDateObj = i.getFields().get("下一年度年检日期");
			if(!Func.isNull(nextAnnualReviewDateObj)){
				// 将nextAnnualReviewDateObj转换为Long，直接取字面值，不能toString
				double nextAnnualReviewDateDouble = (double) nextAnnualReviewDateObj;
				annualReviewDate = (long) nextAnnualReviewDateDouble;
			}
			// 若 deviceCode 和 annualReviewDate 都不为空，则将数据添加到 targets 中
			if(Func.isNotEmpty(deviceCode) && Func.isNotEmpty(annualReviewDate) && Func.isNotEmpty(recordId)) {
				targetsMap.put(deviceCode, annualReviewDate);
				recordIdDeviceCodeMap.put(deviceCode,recordId);
			}
		});
		// 当 deviceCodes 不为空时
		if(Func.isNotEmpty(deviceCodes)){
			annualReviewDateVOList = elevatorAuditService.getAnnualReviewDateByDeviceCodes(deviceCodes);
		}
		// 若 annualReviewDateVOList 不为空，则同步到梯无忧
		if(Func.isNotEmpty(annualReviewDateVOList)){
			Map<String, Object> fieldsMap = new HashMap<>();
			fieldsMap.put("梯无忧成功同步下次年检时间", true);
            annualReviewDateVOList.forEach(vo -> {
				if(targetsMap.containsKey(vo.getDeviceCode())){
					String deviceCode = vo.getDeviceCode();
					ElevatorAudit elevatorAudit = vo.getElevatorAudit();
					// 获取 targetsMap 中对应 deviceCode 的 annualReviewDate
					Long annualReviewDate = (Long) targetsMap.get(deviceCode);
					// 将该 long 值转换成 yyyy-MM-dd string 值
					String annualReviewDateString = DateUtil.format(
						new Date(annualReviewDate),
						"yyyy-MM-dd"
					);
					elevatorAudit.setAuditTime(annualReviewDateString);
					targetElevatorAuditList.add(elevatorAudit);

					AppTableRecord record = AppTableRecord.newBuilder()
						.fields(fieldsMap)
						.recordId(recordIdDeviceCodeMap.get(deviceCode))
						.build();
					updateRecords.add(record);
				}
			});
		}

		// 梯无忧执行更新
		if(Func.isNotEmpty(targetElevatorAuditList)){
			isSuccess = elevatorAuditService.updateBatchById(targetElevatorAuditList);
		}

		// 3. 飞书更新数据：根据设备注册代码更新飞书的年审日期进梯无忧，更新的行，飞书表格单选框选择。
		// 将 updateRecords 转换为数组
		AppTableRecord[] updateRecordsArray = updateRecords.toArray(new AppTableRecord[0]);
		BatchUpdateAppTableRecordReq updateReq = BatchUpdateAppTableRecordReq.newBuilder()
			.appToken(appToken)
			.tableId(tableId)
			.batchUpdateAppTableRecordReqBody(BatchUpdateAppTableRecordReqBody.newBuilder()
				.records(updateRecordsArray)
				.build())
			.build();
		BatchUpdateAppTableRecordResp batchUpdateAppTableRecordResp = feiShuDocumentService.updateRecordsBatch(client, updateReq);

		isSuccess &= batchUpdateAppTableRecordResp.success();

		// 4. 将梯无忧执行结果、飞书执行结果推送消息卡片
		FeiShuTableAnnualReviewDateCopyTemplate feiShuTableAnnualReviewDateCopyTemplate = new FeiShuTableAnnualReviewDateCopyTemplate();
		String message = "飞书多维表格用户触发" + FeiShuDocumentEnum.getDescription(appToken,tableId) + "结果：" + (isSuccess ? "更新成功" : "没有更新成功");
		String messageToSend = String.format(feiShuTableAnnualReviewDateCopyTemplate.getGroupMessageTemplate(),message);
		List<JSONObject> targetGroupObjects = feiShuDocumentService.commandQueryGroupsBatch();
		List<String> chatIds = new ArrayList<>();
		targetGroupObjects.forEach(t -> chatIds.add(t.getString("chat_id")));
		// 发送消息
		chatIds.forEach(c -> {
			CreateMessageReq createMessageReq = new CreateMessageReq();
			createMessageReq.setReceiveIdType("chat_id");
			CreateMessageReqBody createMessageReqBody = new CreateMessageReqBody();
			createMessageReqBody.setMsgType("interactive");
			createMessageReqBody.setReceiveId(c);
			createMessageReqBody.setContent(messageToSend);
			createMessageReq.setCreateMessageReqBody(createMessageReqBody);
			CreateMessageResp createMessageResp = null;
			try {
				createMessageResp = client.im().v1().message().create(createMessageReq);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		});
		return R.data(isSuccess);
	}

	@GetMapping("/formal")
	@ApiOperation("正式环境根据设备注册代码将数据写回正本")
	@ApiOperationSupport(order = 10)
	public R<Boolean> formal() {
		// 1. 创建 Client 对象
		Client client = feiShuConfiguration.getClient(FeishuClientEnum.TABLE);
		// 获取 appToken 和 tableId
		String appToken = FeiShuDocumentEnum.ELEVATOR_ANNUAL_REVIEW_DATE.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_ANNUAL_REVIEW_DATE.getTableId();
		// 发起初始请求
		SearchAppTableRecordResp resp = null;
		try {
			resp = feiShuDocumentService.getRecordsByCondition(client,appToken,tableId,new SearchAppTableRecordReqBody(),null);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		// 处理服务端错误
		if(!resp.success()) {
			throw new ServiceException(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));
		}
		// 定义 Items 接受对象并接受第一次请求的对象，持续接受 Items 直到没有更多数据
		List<AppTableRecord> items = new ArrayList<>(Arrays.asList(resp.getData().getItems()));
		// 若存在下一页,则继续请求下一页，直到没有更多数据
		while(resp.getData().getHasMore()){
			// 定义下一页请求对象, 其中，查询参数请参考飞书官方文档
			String pageToken = resp.getData().getPageToken();
			resp = feiShuDocumentService.getRecordsByCondition(client,appToken,tableId,new SearchAppTableRecordReqBody(),pageToken);
			if(!resp.success()) {
				throw new ServiceException(String.format("code:%s,msg:%s,reqId:%s", resp.getCode(), resp.getMsg(), resp.getRequestId()));
			}
			items.addAll(Arrays.asList(resp.getData().getItems()));
		}
		// 2. 业务数据处理：根据设备注册代码同步飞书的年审日期进梯无忧，同步的行，飞书表格单选框选择。
		boolean isSuccess = true;
		// 可同步至梯无忧的targets
		Map<String, Object> targetsMap = new HashMap<>(100);
		// 同步对象列表
		List<ElevatorAudit> targetElevatorAuditList = new ArrayList<>();
		// 用于筛选的 deviceCodes
		List<String> deviceCodes = new ArrayList<>();
		// 筛选结果
		List<FeiShuAnnualReviewDateVO> annualReviewDateVOList = new ArrayList<>();
		// recordId， deviceCode Map, 用于记录已同步的记录
		Map<String, String> recordIdDeviceCodeMap = new HashMap<>();
		// 飞书更新对象列表
		List<AppTableRecord> updateRecords = new ArrayList<>();

		// 当 items 为空时
		if(Func.isEmpty(items)){
			return R.data(true);
		}

		// 当 items 不为空时
		items.forEach(i -> {
			// 适配最新的FeiShuAPI，以下是所需数据转换
			String deviceCode = null;
			Long annualReviewDate = null;
			String recordId = i.getRecordId();
			Object deviceCodeObj = i.getFields().get("设备注册代码");

			if(!Func.isNull(deviceCodeObj)){
				// 将 deviceCodeObj 转换为 jsonArray
				String deviceCodeObjJsonArrayStr = JSON.toJSONString(deviceCodeObj);
				JSONArray deviceCodeJsonArray = JSON.parseArray(deviceCodeObjJsonArrayStr);
				Object deviceCodeObject = deviceCodeJsonArray.get(0);
				// 将 deviceCodeObject 转换为JsonObject
				String deviceCodeJsonObjectStr = JSON.toJSONString(deviceCodeObject);
				JSONObject deviceCodeJsonObject = JSON.parseObject(deviceCodeJsonObjectStr);
				deviceCode = deviceCodeJsonObject.getString("text");
				deviceCodes.add(deviceCode);
			}
			Object nextAnnualReviewDateObj = i.getFields().get("下一年度年检日期");
			if(!Func.isNull(nextAnnualReviewDateObj)){
				// 将nextAnnualReviewDateObj转换为Long，直接取字面值，不能toString
				double nextAnnualReviewDateDouble = (double) nextAnnualReviewDateObj;
				annualReviewDate = (long) nextAnnualReviewDateDouble;
			}
			// 若 deviceCode 和 annualReviewDate 都不为空，则将数据添加到 targets 中
			if(Func.isNotEmpty(deviceCode) && Func.isNotEmpty(annualReviewDate) && Func.isNotEmpty(recordId)) {
				targetsMap.put(deviceCode, annualReviewDate);
				recordIdDeviceCodeMap.put(deviceCode,recordId);
			}
		});
		// 当 deviceCodes 不为空时
		if(Func.isNotEmpty(deviceCodes)){
			annualReviewDateVOList = elevatorAuditService.getAnnualReviewDateByDeviceCodes(deviceCodes);
		}
		// 若 annualReviewDateVOList 不为空，则同步到梯无忧
		if(Func.isNotEmpty(annualReviewDateVOList)){
			Map<String, Object> fieldsMap = new HashMap<>();
			fieldsMap.put("梯无忧成功同步下次年检时间", true);
			annualReviewDateVOList.forEach(vo -> {
				if(targetsMap.containsKey(vo.getDeviceCode())){
					String deviceCode = vo.getDeviceCode();
					ElevatorAudit elevatorAudit = vo.getElevatorAudit();
					// 获取 targetsMap 中对应 deviceCode 的 annualReviewDate
					Long annualReviewDate = (Long) targetsMap.get(deviceCode);
					// 将该 long 值转换成 yyyy-MM-dd string 值
					String annualReviewDateString = DateUtil.format(
						new Date(annualReviewDate),
						"yyyy-MM-dd"
					);
					elevatorAudit.setAuditTime(annualReviewDateString);
					targetElevatorAuditList.add(elevatorAudit);

					AppTableRecord record = AppTableRecord.newBuilder()
						.fields(fieldsMap)
						.recordId(recordIdDeviceCodeMap.get(deviceCode))
						.build();
					updateRecords.add(record);
				}
			});
		}

		// 梯无忧执行更新
		if(Func.isNotEmpty(targetElevatorAuditList)){
			isSuccess = elevatorAuditService.updateBatchById(targetElevatorAuditList);
		}

		// 3. 飞书更新数据：根据设备注册代码更新飞书的年审日期进梯无忧，更新的行，飞书表格单选框选择。
		// 将 updateRecords 转换为数组
		AppTableRecord[] updateRecordsArray = updateRecords.toArray(new AppTableRecord[0]);
		BatchUpdateAppTableRecordReq updateReq = BatchUpdateAppTableRecordReq.newBuilder()
			.appToken(appToken)
			.tableId(tableId)
			.batchUpdateAppTableRecordReqBody(BatchUpdateAppTableRecordReqBody.newBuilder()
				.records(updateRecordsArray)
				.build())
			.build();
		BatchUpdateAppTableRecordResp batchUpdateAppTableRecordResp = feiShuDocumentService.updateRecordsBatch(client, updateReq);

		isSuccess &= batchUpdateAppTableRecordResp.success();

		// 4. 将梯无忧执行结果、飞书执行结果推送消息卡片
		FeiShuTableAnnualReviewDateTemplate feiShuTableAnnualReviewDateTemplate = new FeiShuTableAnnualReviewDateTemplate();
		String message = "飞书多维表格用户触发" + FeiShuDocumentEnum.getDescription(appToken,tableId) + "结果：" + (isSuccess ? "更新成功" : "没有更新成功");
		String targetUrl = "https://gtech-gd.feishu.cn/base/" + appToken + "?table=" + tableId;
		// url 全部替换
		String messageToSend = String.format(
			feiShuTableAnnualReviewDateTemplate.getGroupMessageTemplate(),
			message,
			targetUrl,targetUrl,targetUrl,targetUrl);
		List<JSONObject> targetGroupObjects = feiShuDocumentService.commandQueryGroupsBatch();
		List<String> chatIds = new ArrayList<>();
		targetGroupObjects.forEach(t -> chatIds.add(t.getString("chat_id")));
		// 发送消息
		chatIds.forEach(c -> {
			CreateMessageReq createMessageReq = new CreateMessageReq();
			createMessageReq.setReceiveIdType("chat_id");
			CreateMessageReqBody createMessageReqBody = new CreateMessageReqBody();
			createMessageReqBody.setMsgType("interactive");
			createMessageReqBody.setReceiveId(c);
			createMessageReqBody.setContent(messageToSend);
			createMessageReq.setCreateMessageReqBody(createMessageReqBody);
			CreateMessageResp createMessageResp = null;
			try {
				createMessageResp = client.im().v1().message().create(createMessageReq);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		});
		return R.data(isSuccess);
	}
}
